`include "mycpu.h"

module TH_stage(
 input  [`DS_TO_TH_BUS_WD -1:0]         ds_to_th_bus,
 input  [`ES_TO_TH_BUS_WD -1:0  ]       es_to_th_bus,
 input  [`MS_TO_TH_BUS_WD -1:0  ]         ms_to_th_bus,
 input  [`_TO_TH_BUS_WD -1:0  ]         ws_to_th_bus,

 output [`_OUT_TH_BUS_WD -1:0 ]         data_haza_bus

);

wire 	       data_haza;
wire           ds_valid;
wire           es_valid;
wire           ms_valid;
wire           ws_valid;
wire           ms_gr_we;
wire           es_gr_we;
wire           ws_gr_we;
wire           br_inst;
wire           data_haza_es;
wire           data_haza_ms;
wire           data_haza_ws;
wire [4:0]     ds_rs;
wire [4:0]     ds_rt;
wire [4:0]     es_dest;
wire [4:0]     ms_dest;
wire [4:0]     ws_dest;
wire [4:0]     ws_c0_com_addr;
wire [4:0]     ms_c0_com_addr;
wire [4:0]     es_c0_com_addr;
wire           ws_op_mfc0;
wire           ms_op_mfc0;
wire           es_op_mfc0;
wire           data_haza_es_c0;
wire           data_haza_ms_c0;
wire           data_haza_ws_c0;
wire           es_load_op;
wire           ds_br_stall;
wire           inst_mfc0;
wire           ms_load_op;
wire           ms_ready_go;
wire           es_br_stall;
wire           ms_br_stall;
wire           ms_op_csr;
wire           es_op_csr;


assign  { 
          ds_valid , //11:11
          br_inst,  //10:10
          ds_rt,//9:5
          ds_rs //4:0
          }= ds_to_th_bus ;
assign  {
         ms_op_csr,
         ms_ready_go,
         ms_load_op,
         ms_valid,
         ms_gr_we, 
         ms_dest    
         }=ms_to_th_bus ;

assign {
         es_op_csr,
         es_load_op,
         es_valid ,//6:6
         es_gr_we ,  //5:5
         es_dest    //4:0
      } =es_to_th_bus ;

assign  {
         ws_gr_we , 
         ws_valid , //5:5
         ws_dest    //4:0
      } = ws_to_th_bus;




// //如果data_haza_es为1就表示ID会与EXE会发生数据冲突
// assign data_haza_es = ~ds_valid || ~es_valid ||  ~es_gr_we || ~(inst_mfc0|| br_inst)         ? 1'b0:
//                       (ds_rs == 5'd0) && (ds_rt ==5'd0)  || (es_dest == 5'd0)  ? 1'b0:
//                       (ds_rs == es_dest)  || (ds_rt == es_dest)                ? 1'b1: 
//                                                                                  1'b0;
// //如果data_haza_ms为1就表示ID会与MEM会发生数据冲突
// assign data_haza_ms = ~ds_valid || ~ms_gr_we  || ~inst_mfc0 || ~ms_valid         ? 1'b0:
//                       (ds_rs == 5'd0) && (ds_rt ==5'd0)   || (ms_dest == 5'd0) ? 1'b0:
//                       (ds_rs == ms_dest) || (ds_rt == ms_dest)                 ? 1'b1: 
//                                                                                 1'b0;
// //如果data_haza_ws为1就表示ID会与WB会发生数据冲突
// assign data_haza_ws = ~ds_valid || ~ws_valid || ~inst_mfc0 || ~ws_gr_we          ? 1'b0:
//                       (ds_rs == 5'd0) && (ds_rt ==5'd0)  || (ws_dest == 5'd0)  ? 1'b0:
//                       (ds_rs == ws_dest)  || (ds_rt == ws_dest)                ? 1'b1:
//                                                                                  1'b0;


assign data_haza_es = ds_valid && es_valid && es_gr_we && ( br_inst || es_load_op || es_op_csr)
                   && (es_dest != 5'd0)
                   && (ds_rs == es_dest || ds_rt == es_dest);

assign data_haza_ms = ds_valid && ms_valid && ms_gr_we && ( ~ms_ready_go || ms_op_csr)//(inst_mfc0 || ms_load_op)
                   && (ms_dest != 5'd0)
                   && (ds_rs == ms_dest || ds_rt == ms_dest);
                   
assign data_haza_ws = ds_valid && ws_valid && ws_gr_we 
                   && (ws_dest != 5'd0)
                   && (ds_rs == ws_dest || ds_rt == ws_dest);

assign es_br_stall  =ds_valid && es_valid &&  es_load_op && br_inst && ((ds_rs == es_dest)  || (ds_rt == es_dest)) ;
assign ms_br_stall  =ds_valid && ms_valid &&  ms_load_op && br_inst && ((ds_rs == ms_dest)  || (ds_rt == ms_dest)) && ~ms_ready_go;
assign ds_br_stall = es_br_stall  || ms_br_stall;
assign data_haza =  data_haza_es || data_haza_ms || data_haza_ws;                                                                                                          
assign data_haza_bus = {ds_br_stall,data_haza};


endmodule  
